//
//  BSKSyncManager.m
//  MicroMemory
//
//  Created by rimi on 16/7/24.
//  Copyright © 2016年 BlueSky. All rights reserved.
//

#import "BSKSyncManager.h"
#import "BSKDBManager.h"
#import <AVOSCloud/AVOSCloud.h>
#import "BSKNoteType.h"
#import "BSKNote.h"
#import "BSKconsts.h"
#import "UIViewController+BSKToast.h"
#import "AFNetworking.h"

@interface BSKSyncManager ()
@property(nonatomic,strong) BSKDBManager * magager;
@property(nonatomic,weak) BSKSyncManager * weakSelf;
@property(nonatomic,assign)BOOL SyncIsStart;
@property(nonatomic,assign)NSInteger willDeleteNoteCount;
@property(nonatomic,assign)NSInteger willDeleteNoteTypeCount;
@property(nonatomic,assign)NSInteger willUploadNoteCount;
@property(nonatomic,assign)NSInteger willUploadNoteTypeCount;
@property(nonatomic,assign)NSInteger willDownloadNoteCount;
@property(nonatomic,assign)NSInteger willDownloadNoteTypeCount;
@property(nonatomic,assign)NSInteger progressCount;
@property(nonatomic,assign)NSTimeInterval updateTime;
@property(nonatomic,strong)UILabel * progressLabel;
@property(nonatomic,assign)UIViewController * controller;
@end

@implementation BSKSyncManager
- (instancetype)init
{
	self = [super init];
	if (self) {
		_magager = [[BSKDBManager alloc]init];
		_weakSelf = self;
		[_magager openDataBase:@"notedatabase.db"];
		_updateTime = [[NSDate date] timeIntervalSince1970];
		_progressLabel = [[UILabel alloc]init];
		_progressLabel.bounds = CGRectMake(0, 0, 100, 30);
		_progressLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
		_progressLabel.layer.cornerRadius = 15;
		_progressLabel.center = CGPointMake(ScreenWidth/2, ScreenHeight*0.7);
	}
	return self;
}

+(instancetype)shareSyncManager{
	static  BSKSyncManager   *  syncManager = nil;
	if (syncManager ==nil) {
		syncManager = [[BSKSyncManager alloc]init];
	}
	return syncManager;
}

-(void)startSyncWithController:(UIViewController *)controller{
	if (_SyncIsStart) {
		return;
	}
	
	__weak typeof(self) weakSelf = self;
	AFNetworkReachabilityManager *rManger = [AFNetworkReachabilityManager sharedManager];
	[rManger startMonitoring];
	[rManger setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
		if (status == AFNetworkReachabilityStatusUnknown || status ==AFNetworkReachabilityStatusNotReachable) {
			[controller MakeToast:@"网络错误，请检查网络" WithTime:2];
		}else{
				[controller MakeToast:@"同步正在后台进行，请稍等" WithTime:1];
				_progressLabel.text = @"";
				_willDownloadNoteTypeCount = LONG_MAX;
				_willDownloadNoteCount = LONG_MAX;
				_controller = controller;
				_progressCount = 0;
				_updateTime = [[NSDate date] timeIntervalSince1970];
				_SyncIsStart = YES;
				[weakSelf addObserver:weakSelf forKeyPath:@"willDeleteNoteTypeCount" options:NSKeyValueObservingOptionNew context:nil];
				[weakSelf addObserver:weakSelf forKeyPath:@"willUploadNoteTypeCount" options:NSKeyValueObservingOptionNew context:nil];
				[weakSelf addObserver:weakSelf forKeyPath:@"willDownloadNoteTypeCount" options:NSKeyValueObservingOptionNew context:nil];
				[weakSelf addObserver:weakSelf forKeyPath:@"willDeleteNoteCount" options:NSKeyValueObservingOptionNew context:nil];
				[weakSelf addObserver:weakSelf forKeyPath:@"willUploadNoteCount" options:NSKeyValueObservingOptionNew context:nil];
				[weakSelf addObserver:weakSelf forKeyPath:@"willDownloadNoteCount" options:NSKeyValueObservingOptionNew context:nil];
				
				[weakSelf updateDeletedNoteType];//删除本地已删除的数据
				[weakSelf uploadType];//同步本地和云端数据
				[weakSelf downLoadNoteType];//下载本地没有的云端数据
				
				[weakSelf updateDeletedNote];
				[weakSelf uploadNote];
				[weakSelf downLoadNote];
		}
	}];
}

#pragma mark 键值观察的方法，判断是否同步结束。

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
	NSInteger count =_willDeleteNoteTypeCount+_willUploadNoteTypeCount+_willDownloadNoteTypeCount+_willDeleteNoteCount+_willUploadNoteCount+_willDownloadNoteCount;
	if (count == 0) {
		NSLog(@"同步完成！");
		[_controller MakeToast:@"同步完成" WithTime:2];
		_SyncIsStart = NO;
		[[NSNotificationCenter defaultCenter]postNotificationName:BSKtypeListChangeNotification object:nil];
		[self removeObserver:self forKeyPath:@"willDeleteNoteTypeCount" ];
		[self removeObserver:self forKeyPath:@"willUploadNoteTypeCount" ];
		[self removeObserver:self forKeyPath:@"willDownloadNoteTypeCount" ];
		[self removeObserver:self forKeyPath:@"willDeleteNoteCount" ];
		[self removeObserver:self forKeyPath:@"willUploadNoteCount" ];
		[self removeObserver:self forKeyPath:@"willDownloadNoteCount" ];
	}
	else{
//		NSLog(@"【1】willDeleteNoteTypeCount:\t%ld",(long)_willDeleteNoteTypeCount);
//		NSLog(@"【2】willUploadNoteTypeCount:\t%ld",_willUploadNoteTypeCount);
//		NSLog(@"【3】willDownloadNoteTypeCount:\t%ld",_willDownloadNoteTypeCount);
//		NSLog(@"【4】willDeleteNoteCount:\t%ld",_willDeleteNoteCount);
//		NSLog(@"【5】willUploadNoteCount:\t%ld",_willUploadNoteCount);
//		NSLog(@"【6】willDownloadNoteCount:\t%ld",_willDownloadNoteCount);
//		NSLog(@"【7】_progressCount:\t%ld",_progressCount);
	}
}

//========================

#pragma mark 同步分类

-(void)updateDeletedNoteType{
	AVUser * user = [AVUser currentUser];
	FMResultSet * resultset = [_magager queryDataFromTable:@"type" Columnns:@[@"*"] condition:[NSString stringWithFormat:@" pictureFileName = 'null' and userID = '%@'",user.objectId]];
	NSMutableArray * willDeletedTypes = [NSMutableArray array];
	while([resultset next]){
		BSKNoteType * type = [BSKNoteType typeWithResultSet:resultset];
		[willDeletedTypes addObject:type];
	}
	[resultset close];
	[_magager.fmDatabase close];
	if (willDeletedTypes.count==0) {
		return;
	}
	_weakSelf.willDeleteNoteTypeCount = willDeletedTypes.count;
	_progressCount+=willDeletedTypes.count;
	
	for (BSKNoteType * type in willDeletedTypes) {
		if ([type.objectID isEqualToString:@"null"]) {
			//是否已经同步过了，如果没有则直接删除本地数据
			NSLog(@"删除：%@",type);
			[_magager deleteDataFromTable:@"type" condition:[NSString stringWithFormat:@"typeID = '%@'",type.typeID]];
			_weakSelf.willDeleteNoteTypeCount=_weakSelf.willDeleteNoteTypeCount-1;
		}
		else{
			//读取网络上的该条数据并删除
			AVQuery *query = [AVQuery queryWithClassName:@"Type"];
			[query getObjectInBackgroundWithId:type.objectID block:^(AVObject *object, NSError *error) {
				if (error) {
					if (error.code == 101) {
						NSLog(@"删除：%@",type);
						[_magager deleteDataFromTable:@"type" condition:[NSString stringWithFormat:@"typeID = '%@'",type.typeID]];
						_weakSelf.willDeleteNoteTypeCount=_weakSelf.willDeleteNoteTypeCount-1;
					}else{
						NSLog(@"删除分类：网络删除失败—ERRO：%@",error);
						_weakSelf.willDeleteNoteTypeCount=_weakSelf.willDeleteNoteTypeCount-1;
					}
				}else{
					NSString * picturename = [object objectForKey:@"pictureFileName"];
					if (![[picturename substringToIndex:12] isEqualToString:@"localHost://"]) {
						AVQuery *query = [AVQuery queryWithClassName:@"_File"];
						[query whereKey:@"url" equalTo:picturename];
						[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
							if (error) {
								NSLog(@"ERRO:-10:%@",error);
								return ;
							}
							NSArray<AVFile *> *noteFiles = objects;
							for (AVFile *file in noteFiles) {
								[file deleteInBackground];
							}
						}];
					}
					[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
						if (error) {
							NSLog(@"删除分类：网络删除失败—ERRO：%@",error);
							_weakSelf.willDeleteNoteTypeCount=_weakSelf.willDeleteNoteTypeCount-1;
						}else{
							NSLog(@"删除：%@",type);
							[_magager deleteDataFromTable:@"type" condition:[NSString stringWithFormat:@"typeID = '%@'",type.typeID]];
							_weakSelf.willDeleteNoteTypeCount=_weakSelf.willDeleteNoteTypeCount-1;
						}
					}];
				}
			}];
		}
	}
}


-(void)uploadType{
	AVUser * user = [AVUser currentUser];
	FMResultSet * resultset = [_magager queryDataFromTable:@"type" Columnns:@[@"*"] condition:[NSString stringWithFormat:@"userID = '%@' and pictureFileName !='null'",user.objectId]];
	NSMutableArray * willUpdateTypes = [NSMutableArray array];
	while([resultset next]){
		BSKNoteType * type = [BSKNoteType typeWithResultSet:resultset];
		[willUpdateTypes addObject:type];
	}
	[resultset close];
	[_magager.fmDatabase close];
	if (willUpdateTypes.count==0) {
		return;
	}
	_weakSelf.willUploadNoteTypeCount = willUpdateTypes.count;
	_progressCount+=willUpdateTypes.count;
	
	for (BSKNoteType * type in willUpdateTypes) {
		if ([type.objectID isEqualToString:@"null"]) {
			//·如果还没有上传则上传该数据
			[_weakSelf uploadType:type];
		}
		else{//如果曾经上传过
			//读取网络上的该条数据
			AVQuery *query = [AVQuery queryWithClassName:@"Type"];
			[query getObjectInBackgroundWithId:type.objectID block:^(AVObject *object, NSError *error) {
				if (!object) {
					if (error.code == 101) {
						//·网络上没有该数据，则删除本地数据
						if (![[type.pictureFileName substringToIndex:12] isEqualToString:@"localHost://"]) {
							NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
							NSString * picFilePath = [NSString stringWithFormat:@"%@/%@",typeImageDirPath,type.pictureFileName];
							[[NSFileManager defaultManager] removeItemAtPath:picFilePath error:nil];
						}
						
						FMResultSet * resultSet = [_magager queryDataFromTable:@"note" Columnns:@[@"*"] condition:[NSString stringWithFormat:@"typeID = '%@' and userID = '%@'",type.typeID,user.objectId]];
						NSMutableArray * willDeleteNotes = [NSMutableArray array];
						while ([resultSet next]) {
							BSKNote *note = [BSKNote noteWithResultSet:resultSet];
							[willDeleteNotes addObject:note];
						}
						[resultSet close];
						[_magager.fmDatabase close];
						
						for(BSKNote * deleteNote in willDeleteNotes) {
							NSString * noteDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
							NSFileManager *fileManager = [NSFileManager defaultManager];
							NSString *fileName = deleteNote.noteFileName;
							NSError *error = [[NSError alloc] init];
							[fileManager removeItemAtPath:[NSString stringWithFormat:@"%@/%@",noteDirPath,fileName] error:&error];
							[_magager updateDataToTable:@"note" Columnns:@[@[@"noteFileName", @"null"]] condition:[NSString stringWithFormat:@"noteID = '%@' and userID = '%@'", deleteNote.noteID,user.objectId]];
					}
					NSLog(@"删除：%@",type);
					[_magager deleteDataFromTable:@"type" condition:[NSString stringWithFormat:@" typeID = '%@'",type.typeID]];
					_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
					}
					else{
						NSLog(@"ERRO:-1:%@",error);
						_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
					}
				}else{
					NSNumber * updateTime = [object objectForKey:@"updateTime"];
					if (type.updateTime > [updateTime doubleValue]) {
						//如果本地比网络新，则上传网络
						[_weakSelf uploadType:type withAVobject:object];
					}else if(type.updateTime < [updateTime doubleValue]){
						//如果网络比本地新，下载网络
						[_weakSelf DownloadType:type withAVobject:object];
					}
					else{
						_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
					}
				}
			}];
			
		}
	}
}

-(void)downLoadNoteType{
	
	AVUser *user = [AVUser currentUser];
	AVQuery * query = [AVQuery queryWithClassName:@"Type"];
	[query whereKey:@"userID" equalTo:user.objectId];
	[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
		
		if (error) {
			if (error.code == 101) {
				_weakSelf.willDownloadNoteTypeCount = 0;
			}
			else{
				NSLog(@"ERRO:-2:%@",error);
				_weakSelf.willDownloadNoteTypeCount = 0;
			}
			return ;
		}
		
		//查询所有云端的数据，和本地比对
		_weakSelf.willDownloadNoteTypeCount = objects.count;
		_progressCount+=objects.count;
		for (AVObject * typeObj in objects) {
			NSString * typeID = [typeObj objectForKey:@"typeID"];
			FMResultSet * resultset = [_magager queryDataFromTable:@"type" Columnns:@[@"*"] condition:[NSString stringWithFormat:@"typeID = '%@' and userID = '%@'",typeID,user.objectId]];
			NSInteger count = 0;
			while ([resultset next]) {
				count +=1;
			}
			[resultset close];
			[_magager.fmDatabase close];
			
			if (count == 0) {//如果本地没有，则下载
				[_weakSelf DownloadTypeWithAVobject:typeObj];
			}else{
				//如果本地有则什么也不不做;
				_weakSelf.willDownloadNoteTypeCount = _weakSelf.willDownloadNoteTypeCount -1;
			}
		}
	}];
	
}



#pragma mark 同步日记
-(void)updateDeletedNote{
	AVUser * user = [AVUser currentUser];
	FMResultSet * resultset2 = [_magager queryDataFromTable:@"note" Columnns:@[@"*"] condition:[NSString stringWithFormat:@" noteFileName = 'null' and userID = '%@'",user.objectId]];
	NSMutableArray * willDeletedNotes = [NSMutableArray array];
	while([resultset2 next]){
		BSKNote * note = [BSKNote noteWithResultSet:resultset2];
		[willDeletedNotes addObject:note];
	}
	[resultset2 close];
	[_magager.fmDatabase close];
	
	if (willDeletedNotes.count ==0) {
		return;
	}
	
	_weakSelf.willDeleteNoteCount = willDeletedNotes.count;
	_progressCount+=willDeletedNotes.count;
	
	for (NSInteger index = 0;index<willDeletedNotes.count;index++) {
		BSKNote * Note = [willDeletedNotes objectAtIndex:index];
		if ([Note.objectID isEqualToString:@"null"]) {
			//是否已经同步过了，如果没有则直接删除本地数据
			NSLog(@"删除：%@",Note);
			[_magager deleteDataFromTable:@"note" condition:[NSString stringWithFormat:@"noteID = '%@'",Note.noteID]];
			_weakSelf.willDeleteNoteCount=_weakSelf.willDeleteNoteCount-1;
		}
		else{
			//读取网络上的该条数据并删除
			AVQuery *query = [AVQuery queryWithClassName:@"Note"];
			[query getObjectInBackgroundWithId:Note.objectID block:^(AVObject *object, NSError *error) {
				if (error) {
					NSLog(@"ERRO:-3:%@",error);
					_weakSelf.willDeleteNoteCount=_weakSelf.willDeleteNoteCount-1;
					return ;
				}
				AVQuery *query = [AVQuery queryWithClassName:@"_File"];
				[query whereKey:@"url" equalTo:[object objectForKey:@"noteFileName"]];
				[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
					if (error) {
						NSLog(@"ERRO:-18:%@",error);
						return ;
					}
					NSArray<AVFile *> *noteFiles = objects;
					for (AVFile *file in noteFiles) {
						[file deleteInBackground];
					}
				}];
				
				[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
					if (!succeeded) {
						NSLog(@"ERRO:-4:%@",error);
						_weakSelf.willDeleteNoteCount=_weakSelf.willDeleteNoteCount-1;
						return ;
					}
					[_magager deleteDataFromTable:@"note" condition:[NSString stringWithFormat:@"noteID = '%@'",Note.noteID]];
					_weakSelf.willDeleteNoteCount=_weakSelf.willDeleteNoteCount-1;
				}];
			}];
		}
	}

}


-(void)uploadNote{
	AVUser * user = [AVUser currentUser];
	FMResultSet * resultSet = [_magager queryDataFromTable:@"note" Columnns:@[@"*"] condition:[NSString stringWithFormat:@"userID = '%@' and noteFileName !='null'",user.objectId]];
	NSMutableArray * willUpdateNotes = [NSMutableArray array];
	while([resultSet next]){
		BSKNote *note = [[BSKNote alloc] init];
		note.isChange = [resultSet boolForColumn:		@"isChange"];
		note.objectID = [resultSet stringForColumn:		@"objectID"];
		note.typeID = [resultSet stringForColumn:		@"typeID"];
		note.userID = [resultSet stringForColumn:		@"userID"];
		note.noteID = [resultSet stringForColumn:		@"noteID"];
		note.title = [resultSet stringForColumn:		@"title"];
		note.date = [resultSet stringForColumn:			@"date"];
		note.address = [resultSet stringForColumn:		@"address"];
		note.subcontent = [resultSet stringForColumn:	@"subcontent"];
		note.noteFileName = [resultSet stringForColumn:	@"noteFileName"];
		note.updateTime = [resultSet doubleForColumn:	@"updateTime"];
		note.latitude = [resultSet doubleForColumn:		@"latitude"];
		note.longitude = [resultSet doubleForColumn:	@"longitude"];
		note.weatherType = [resultSet intForColumn:		@"weatherType"];
		[willUpdateNotes addObject:note];
	}
	[resultSet close];
	[_magager.fmDatabase close];
	
	if (willUpdateNotes.count==0) {
		return;
	}
	_weakSelf.willUploadNoteCount = willUpdateNotes.count;
	_progressCount+=willUpdateNotes.count;
	
	for (BSKNote * note in willUpdateNotes) {
		if ([note.objectID isEqualToString:	@"null"]) {
			//·如果还没有上传则上传该数据
			[_weakSelf uploadNote:note];
		}
		else{//如果曾经上传过
			//读取网络上的该条数据
			AVQuery *query = [AVQuery queryWithClassName:@"Note"];
			[query getObjectInBackgroundWithId:note.objectID block:^(AVObject *object, NSError *error) {
				if (!object) {
					if (error.code == 101) {
						//·网络上没有该数据，则删除本地数据
						NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
						NSString * picFilePath = [NSString stringWithFormat:@"%@/%@",typeImageDirPath,note.noteFileName];
						[[NSFileManager defaultManager] removeItemAtPath:picFilePath error:nil];
						NSLog(@"删除：%@",note);
						[_magager deleteDataFromTable:@"note" condition:[NSString stringWithFormat:@" noteID = '%@'",note.noteID]];
						_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
					}else{
						NSLog(@"ERRO:-5:%@",error);
						_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
					}
					
				}else{
					
					if (note.isChange) {
						NSNumber * updateTime = [object objectForKey:@"updateTime"];
						NSLog(@"本地已编辑：本地时间：%lf网络时间：%lf",note.updateTime,[updateTime doubleValue]);
						if (note.updateTime >= [updateTime doubleValue]) {
							//如果本地比网络新，则上传网络
							[_weakSelf uploadNote:note withAVobject:object];
						}else {
							//如果网络比本地新,发生冲突 保留两者
							[_weakSelf uploadNoteWithNewNoteID:note];
							[_weakSelf DownloadNote:note withAVobject:object];
						}
					}
					else{
						NSNumber * updateTime = [object objectForKey:@"updateTime"];
						NSLog(@"本地未编辑：本地时间：%lf网络时间：%lf",note.updateTime,[updateTime doubleValue]);
						if(note.updateTime < [updateTime doubleValue]){
							//如果网络比本地新，下载网络
							[_weakSelf DownloadNote:note withAVobject:object];
						}
						else{
							_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
						}
					}
				}
			}];
		}
	}
}

-(void)downLoadNote{
	
	AVUser *user = [AVUser currentUser];
	AVQuery * query = [AVQuery queryWithClassName:@"Note"];
	[query whereKey:@"userID" equalTo:user.objectId];
	[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
		//查询所有云端的数据，和本地比对
		if (!objects) {
			if (error.code == 101) {
				_weakSelf.willDownloadNoteCount = 0;
			}
			else{
				NSLog(@"ERRO:-6:%@",error);
				_weakSelf.willDownloadNoteCount = 0;
			}
			return ;
		}
		_weakSelf.willDownloadNoteCount = objects.count;
		_progressCount+=objects.count;
		for (AVObject * noteObject in objects) {
			
			NSString * noteID = [noteObject objectForKey:@"noteID"];
			FMResultSet * resultset = [_magager queryDataFromTable:@"note" Columnns:@[@"*"] condition:[NSString stringWithFormat:@"noteID = '%@' and userID = '%@'",noteID,user.objectId]];
			NSInteger count = 0;
			while ([resultset next]) {
				count +=1;
			}
			[resultset close];
			[_magager.fmDatabase close];
			if (count == 0) {//如果本地没有，则下载
				[_weakSelf DownloadNoteWithAVobject:noteObject];
			}else{
				//如果本地有则什么也不不做;
				_weakSelf.willDownloadNoteCount = _weakSelf.willDownloadNoteCount -1;
			}
		}
	}];
}

#pragma mark 日记同步的工具方法
-(void)uploadNoteWithNewNoteID:(BSKNote *)note{
	NSInteger Createtime = (NSInteger)([NSDate date].timeIntervalSince1970*100);
	NSString * newNoteID =  [NSString stringWithFormat:@"%ld",(long)Createtime];
	NSString *newNoteFileName = [NSString stringWithFormat:@"%@.rtfd",newNoteID];
	NSString * noteDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
	NSData * noteData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",noteDirPath,note.noteFileName]];
	NSFileManager * fileManager = [NSFileManager defaultManager];
	[fileManager createFileAtPath:[NSString stringWithFormat:@"%@/%@",noteDirPath,newNoteFileName] contents:noteData attributes:nil];
	
	AVFile * noteFile = [AVFile fileWithName:newNoteFileName data:noteData];
	[noteFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
		if (!succeeded) {
			NSLog(@"ERRO%@",error);
			return ;
		}
		AVObject * noteObject = [AVObject objectWithClassName:@"Note"];
		[noteObject setObject:newNoteID forKey:@"noteID"];
		[noteObject setObject:[NSNumber numberWithBool:NO ] forKey:@"isChange"];
		[noteObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
		[noteObject setObject:note.userID forKey:@"userID"];
		[noteObject setObject:note.typeID forKey:@"typeID"];
		[noteObject setObject:[NSString stringWithFormat:@"%@-冲突",note.title] forKey:@"title"];
		[noteObject setObject:[NSNumber numberWithDouble:note.latitude] forKey:@"latitude"];
		[noteObject setObject:[NSNumber numberWithDouble:note.longitude] forKey:@"longitude"];
		[noteObject setObject:[NSNumber numberWithInt:note.weatherType] forKey:@"weatherType"];
		[noteObject setObject:note.date forKey:@"date"];
		[noteObject setObject:note.address forKey:@"address"];
		[noteObject setObject:note.subcontent forKey:@"subcontent"];
		[noteObject setObject:noteFile.url forKey:@"noteFileName"];
		[noteObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			
			if (error) {
				NSLog(@"ERRO:-7:%@",error);
				return ;
			}
			
		[_magager insertDataToTable:@"note"
						   Columnns:@[@[@"noteID",		newNoteID],
									  @[@"objectID",	noteObject.objectId],//表示当前的日记是否已经同步
									  @[@"isChange",	@"0"],//表示当前日记是否已经更改
									  @[@"updateTime",	[NSNumber numberWithDouble:_updateTime]],//最后一次更新时间
									  @[@"userID",		note.userID],
									  @[@"typeID",		note.typeID],
									  @[@"title",		[NSString stringWithFormat:@"%@-冲突",note.title]],
									  @[@"latitude",		[NSNumber numberWithDouble:note.latitude]],//经度
									  @[@"longitude",	[NSNumber numberWithDouble:note.longitude]],//纬度
									  @[@"weatherType",	[NSNumber numberWithInt:note.weatherType]],
									  @[@"date",		note.date],
									  @[@"address",		note.address],
									  @[@"subcontent",	note.subcontent],
									  @[@"noteFileName",newNoteFileName]]];
		}];
		
	}];
	
}
-(void)uploadNote:(BSKNote *)note{
	AVUser * user = [AVUser currentUser];
	NSString * noteDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
	NSData * noteData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",noteDirPath,note.noteFileName]];
	AVFile * noteFile = [AVFile fileWithName:note.noteFileName data:noteData];
	[noteFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
		if (!succeeded) {
			NSLog(@"ERRO:-8:%@",error);
			_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
			return ;
		}
		AVObject * noteObject = [AVObject objectWithClassName:@"Note"];
		[noteObject setObject:note.noteID forKey:@"noteID"];
		[noteObject setObject:[NSNumber numberWithBool:NO ] forKey:@"isChange"];
		[noteObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
		[noteObject setObject:note.userID forKey:@"userID"];
		[noteObject setObject:note.typeID forKey:@"typeID"];
		[noteObject setObject:note.title forKey:@"title"];
		[noteObject setObject:[NSNumber numberWithDouble:note.latitude] forKey:@"latitude"];
		[noteObject setObject:[NSNumber numberWithDouble:note.longitude] forKey:@"longitude"];
		[noteObject setObject:[NSNumber numberWithInt:note.weatherType] forKey:@"weatherType"];
		[noteObject setObject:note.date forKey:@"date"];
		[noteObject setObject:note.address forKey:@"address"];
		[noteObject setObject:note.subcontent forKey:@"subcontent"];
		[noteObject setObject:noteFile.url forKey:@"noteFileName"];
		[noteObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			if (error) {
				NSLog(@"ERRO:-9:%@",error);
				_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
				return ;
			}
		[_magager updateDataToTable:@"note" Columnns:@[
													@[@"objectID",noteObject.objectId],
													@[@"updateTime",[NSNumber numberWithDouble:_updateTime]],
													@[@"isChange",@"0"]
													] condition:[NSString stringWithFormat:@"noteID = '%@' and userID = '%@'",note.noteID,user.objectId]];
			_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
		}];
	}];
}
-(void)uploadNote:(BSKNote *)note withAVobject:(AVObject *)noteObject{
	
	NSString * noteFileName = [noteObject objectForKey:@"noteFileName"];
	AVQuery *query = [AVQuery queryWithClassName:@"_File"];
		[query whereKey:@"url" equalTo:noteFileName];
		[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
			if (error) {
				NSLog(@"ERRO:-10:%@",error);
				return ;
			}
			NSArray<AVFile *> *noteFiles = objects;
			for (AVFile *file in noteFiles) {
				[file deleteInBackground];
			}
		}];
	
	
	AVUser * user = [AVUser currentUser];
	NSString * noteDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
	NSData * noteData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",noteDirPath,note.noteFileName]];
	AVFile * noteFile = [AVFile fileWithName:note.noteFileName data:noteData];
	[noteFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
		if(!succeeded){
			NSLog(@"ERRO:-11:%@",error);
			_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
			return ;
		}
		[noteObject setObject:note.noteID forKey:@"noteID"];
		[noteObject setObject:[NSNumber numberWithBool:NO ] forKey:@"isChange"];
		[noteObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
		[noteObject setObject:note.userID forKey:@"userID"];
		[noteObject setObject:note.typeID forKey:@"typeID"];
		[noteObject setObject:note.title forKey:@"title"];
		[noteObject setObject:[NSNumber numberWithDouble:note.latitude] forKey:@"latitude"];
		[noteObject setObject:[NSNumber numberWithDouble:note.longitude] forKey:@"longitude"];
		[noteObject setObject:[NSNumber numberWithInt:note.weatherType] forKey:@"weatherType"];
		[noteObject setObject:note.date forKey:@"date"];
		[noteObject setObject:note.address forKey:@"address"];
		[noteObject setObject:note.subcontent forKey:@"subcontent"];
		[noteObject setObject:noteFile.url forKey:@"noteFileName"];
		[noteObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			if (error) {
				NSLog(@"ERRO:-12:%@",error);
				_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
				return ;
			}
			[_magager updateDataToTable:@"note" Columnns:@[
														   @[@"objectID",noteObject.objectId],
														   @[@"updateTime",[NSNumber numberWithDouble:_updateTime]],
														   @[@"isChange",@"0"]
														   ] condition:[NSString stringWithFormat:@"noteID = '%@' and userID = '%@'",note.noteID,user.objectId]];
			_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;
		}];
	}];
}


-(void)DownloadNote:(BSKNote *)note withAVobject:(AVObject *)noteObject{
	AVUser * user= [AVUser currentUser];
	NSString * DirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
	NSString * noteFileName = [noteObject objectForKey:@"noteFileName"];
	NSURL * noteFileUrl = [NSURL URLWithString:noteFileName];
	NSData * noteFile = [NSData dataWithContentsOfURL:noteFileUrl];
	NSFileManager * filemanager = [NSFileManager defaultManager];
	NSString * FileName = [NSString stringWithFormat:@"%@%@.rtfd",note.noteID,user.objectId];
	[filemanager createFileAtPath:[NSString stringWithFormat:@"%@/%@",DirPath,FileName] contents:noteFile attributes:nil];
	[_magager updateDataToTable:@"note"
						 Columnns:@[@[@"isChange",		@"0"],//表示当前日记是否已经更改
									@[@"title",			[noteObject objectForKey:@"title"]],
									@[@"objectID",		noteObject.objectId],
									@[@"weatherType",	[noteObject objectForKey:@"weatherType"]],
									@[@"date",			[noteObject objectForKey:@"date"]],
									@[@"address",		[noteObject objectForKey:@"address"]],
									@[@"subcontent",	[noteObject objectForKey:@"subcontent"]],
									@[@"updateTime",	[noteObject objectForKey:@"updateTime"]],//最后一次更新时间
									]
						condition: [NSString stringWithFormat:@"noteID = '%@'", note.noteID]];
	_weakSelf.willUploadNoteCount = _weakSelf.willUploadNoteCount-1;

}

-(void)DownloadNoteWithAVobject:(AVObject *)noteObject{
	AVUser * user= [AVUser currentUser];
	NSString * DirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
	NSString * noteFileName = [noteObject objectForKey:@"noteFileName"];
	NSURL * noteFileUrl = [NSURL URLWithString:noteFileName];
	NSData * noteFile = [NSData dataWithContentsOfURL:noteFileUrl];
	NSFileManager * filemanager = [NSFileManager defaultManager];
	NSString * FileName = [NSString stringWithFormat:@"%@%@.rtfd",[noteObject objectForKey:@"noteID"],user.objectId];
	[filemanager createFileAtPath:[NSString stringWithFormat:@"%@/%@",DirPath,FileName] contents:noteFile attributes:nil];
	[_magager insertDataToTable:@"note"
						 Columnns:@[@[@"noteID",		[noteObject objectForKey:@"noteID"]],
									@[@"objectID",		noteObject.objectId],//表示当前的日记是否已经同步
									@[@"isChange",		@"0"],//表示当前日记是否已经更改
									@[@"updateTime",	[noteObject objectForKey:@"updateTime"]],//最后一次更新时间
									@[@"userID",		[noteObject objectForKey:@"userID"]],
									@[@"typeID",		[noteObject objectForKey:@"typeID"]],
									@[@"title",			[noteObject objectForKey:@"title"]],
									@[@"latitude",		[noteObject objectForKey:@"latitude"]],//经度
									@[@"longitude",		[noteObject objectForKey:@"longitude"]],//纬度
									@[@"weatherType",	[noteObject objectForKey:@"weatherType"]],
									@[@"date",			[noteObject objectForKey:@"date"]],
									@[@"address",		[noteObject objectForKey:@"address"]],
									@[@"subcontent",	[noteObject objectForKey:@"subcontent"]],
									@[@"noteFileName",	FileName]]];
	_weakSelf.willDownloadNoteCount = _weakSelf.willDownloadNoteCount-1;
}

#pragma mark 分类同步的工具方法

-(void)uploadType:(BSKNoteType *)type{
	if(![[type.pictureFileName substringToIndex:12] isEqualToString:@"localHost://"]){
		//如果不是自带图片则上传文件
		NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
		NSData * imageData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",typeImageDirPath,type.pictureFileName]];
		AVFile * pictureFile = [AVFile fileWithName:type.pictureFileName data:imageData];
		[pictureFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			AVObject * typeObject = [AVObject objectWithClassName:@"Type"];
			[typeObject setObject:type.typeID forKey:@"typeID"];
			[typeObject setObject:type.userID forKey:@"userID"];
			[typeObject setObject:type.typeName forKey:@"typeName"];
			[typeObject setObject:pictureFile.url forKey:@"pictureFileName"];
			[typeObject setObject:type.password forKey:@"password"];
			[typeObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
			[typeObject setObject:[NSNumber numberWithBool:type.secretMode] forKey:@"secretMode"];
			[typeObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
				if (error) {
					NSLog(@"ERRO:-13:%@",error);
					_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
					return ;
				}
				[_magager updateDataToTable:@"type" Columnns:@[@[@"objectID",typeObject.objectId],@[@"updateTime",[NSString stringWithFormat:@"%lf",_updateTime]]] condition:[NSString stringWithFormat:@"typeID = '%@' ",type.typeID]];
				_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
			}];
		}];
	}else{//如果是自带图片则不上传图片
		AVObject * typeObject = [AVObject objectWithClassName:@"Type"];
		
		[typeObject setObject:type.typeID forKey:@"typeID"];
		[typeObject setObject:type.userID forKey:@"userID"];
		[typeObject setObject:type.typeName forKey:@"typeName"];
		[typeObject setObject:type.pictureFileName forKey:@"pictureFileName"];
		[typeObject setObject:type.password forKey:@"password"];
		[typeObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
		[typeObject setObject:[NSNumber numberWithBool:type.secretMode] forKey:@"secretMode"];
		[typeObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			if (error) {
				NSLog(@"ERRO:-14:%@",error);
				_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
				return ;
			}
			[_magager updateDataToTable:@"type" Columnns:@[@[@"objectID",typeObject.objectId],@[@"updateTime",[NSString stringWithFormat:@"%lf",_updateTime]]] condition:[NSString stringWithFormat:@"typeID = '%@' ",type.typeID]];
			_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
		}];
	}
}

-(void)uploadType:(BSKNoteType *)type withAVobject:(AVObject *)typeObject{
	
	NSString * picturename = [typeObject objectForKey:@"pictureFileName"];
	if (![[picturename substringToIndex:12] isEqualToString:@"localHost://"]) {
		AVQuery *query = [AVQuery queryWithClassName:@"_File"];
		[query whereKey:@"url" equalTo:picturename];
		[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
			NSArray<AVFile *> *headerImages = objects;
			for (AVFile *file in headerImages) {
				[file deleteInBackground];
			}
		}];
	}
	
	if(![[type.pictureFileName substringToIndex:12] isEqualToString:@"localHost://"]){
		//如果不是自带图片则上传文件
		NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
		NSData * imageData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",typeImageDirPath,type.pictureFileName]];
		AVFile * pictureFile = [AVFile fileWithName:type.pictureFileName data:imageData];
		[pictureFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			if (!succeeded) {
				NSLog(@"上传图片失败：ERRO:-15:%@",error);
				_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
				return ;
			}
			[typeObject setObject:type.typeID forKey:@"typeID"];
			[typeObject setObject:type.userID forKey:@"userID"];
			[typeObject setObject:type.typeName forKey:@"typeName"];
			[typeObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
			[typeObject setObject:pictureFile.url forKey:@"pictureFileName"];
			[typeObject setObject:type.password forKey:@"password"];
			[typeObject setObject:[NSNumber numberWithBool:type.secretMode] forKey:@"secretMode"];
			[typeObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
				if (!succeeded) {
					NSLog(@"ERRO:-16:%@",error);
					_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
					return ;
				}
				[_magager updateDataToTable:@"type" Columnns:@[@[@"objectID",typeObject.objectId],@[@"updateTime",[NSString stringWithFormat:@"%lf",_updateTime]]] condition:[NSString stringWithFormat:@"typeID = '%@' ",type.typeID]];
				_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
			}];
		}];
	}else{//如果是自带图片则不上传图片
		[typeObject setObject:type.typeID forKey:@"typeID"];
		[typeObject setObject:type.userID forKey:@"userID"];
		[typeObject setObject:type.typeName forKey:@"typeName"];
		[typeObject setObject:[NSNumber numberWithDouble:_updateTime] forKey:@"updateTime"];
		[typeObject setObject:type.pictureFileName forKey:@"pictureFileName"];
		[typeObject setObject:type.password forKey:@"password"];
		[typeObject setObject:[NSNumber numberWithBool:type.secretMode] forKey:@"secretMode"];
		[typeObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
			if (error) {
			NSLog(@"ERRO:-17:%@",error);
			_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
			return ;
		}
			[_magager updateDataToTable:@"type" Columnns:@[@[@"objectID",typeObject.objectId],@[@"updateTime",[NSString stringWithFormat:@"%lf",_updateTime]]] condition:[NSString stringWithFormat:@"typeID = '%@' ",type.typeID]];
			_weakSelf.willUploadNoteTypeCount = _weakSelf.willUploadNoteTypeCount-1;
		}];
	}
}


-(void)DownloadType:(BSKNoteType *)type withAVobject:(AVObject *)typeObject{
	AVUser * user= [AVUser currentUser];
	NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
	NSString * picturename = [typeObject objectForKey:@"pictureFileName"];
	if (![[picturename substringToIndex:12] isEqualToString:@"localHost://"]) {
		NSURL * pictureURL = [NSURL URLWithString:picturename];
		NSData * pictureFile = [NSData dataWithContentsOfURL:pictureURL];
		NSFileManager * filemanager = [NSFileManager defaultManager];
		NSString * pictureFileName = [NSString stringWithFormat:@"%@%@.jpg",type.typeID,user.objectId];
		[filemanager createFileAtPath:[NSString stringWithFormat:@"%@/%@",typeImageDirPath,pictureFileName] contents:pictureFile attributes:nil];
		[_magager updateDataToTable:@"type" Columnns:@[
												  @[@"typeName",[typeObject objectForKey:@"typeName"]],
												  @[@"updateTime",[typeObject objectForKey:@"updateTime"]],
												  @[@"pictureFileName",pictureFileName],
												  @[@"password",[typeObject objectForKey:@"password"]],
												  @[@"secretMode",[typeObject objectForKey:@"secretMode"]],
												  @[@"objectId",typeObject.objectId]]
						  condition:[NSString stringWithFormat: @"typeID = '%@'",type.typeID]];
		_weakSelf.willDownloadNoteTypeCount = _weakSelf.willDownloadNoteTypeCount-1;
	}else{
		[_magager updateDataToTable:@"type" Columnns:@[
													   @[@"typeName",[typeObject objectForKey:@"typeName"]],
													   @[@"updateTime",[typeObject objectForKey:@"updateTime"]],
													   @[@"pictureFileName",picturename],
													   @[@"password",[typeObject objectForKey:@"password"]],
													   @[@"secretMode",[typeObject objectForKey:@"secretMode"]],
													   @[@"objectId",typeObject.objectId]]
						  condition:[NSString stringWithFormat: @"typeID = '%@'",type.typeID]];
		_weakSelf.willDownloadNoteTypeCount = _weakSelf.willDownloadNoteTypeCount-1;

	}
}


-(void)DownloadTypeWithAVobject:(AVObject *)typeObject{
	AVUser * user= [AVUser currentUser];
	NSString * typeImageDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
	NSString * picturename = [typeObject objectForKey:@"pictureFileName"];
	if (![[picturename substringToIndex:12] isEqualToString:@"localHost://"]) {
		NSURL * pictureURL = [NSURL URLWithString:picturename];
		NSData * pictureFile = [NSData dataWithContentsOfURL:pictureURL];
		NSFileManager * filemanager = [NSFileManager defaultManager];
		NSString * pictureFileName = [NSString stringWithFormat:@"%@%@.jpg",[typeObject objectForKey:@"typeID"],user.objectId];
		[filemanager createFileAtPath:[NSString stringWithFormat:@"%@/%@",typeImageDirPath,pictureFileName] contents:pictureFile attributes:nil];
		[_magager insertDataToTable:@"type" Columnns:@[
													   @[@"typeID",		[typeObject objectForKey:@"typeID"]],
													   @[@"userID",		[typeObject objectForKey:@"userID"]],
													   @[@"typeName",	[typeObject objectForKey:@"typeName"]],
													   @[@"objectID",	typeObject.objectId],
													   @[@"updateTime",	[typeObject objectForKey:@"updateTime"]],//上次修改时间
													   @[@"pictureFileName",pictureFileName],
													   @[@"secretMode",	[typeObject objectForKey:@"secretMode"]],
													   @[@"password",	[typeObject objectForKey:@"password"]],
													   ]];
		_weakSelf.willDownloadNoteTypeCount = _weakSelf.willDownloadNoteTypeCount-1;
	}else{
		[_magager insertDataToTable:@"type" Columnns:@[
													   @[@"typeID",			[typeObject objectForKey:@"typeID"]],
													   @[@"userID",			[typeObject objectForKey:@"userID"]],
													   @[@"typeName",		[typeObject objectForKey:@"typeName"]],
													   @[@"objectID",		typeObject.objectId],
													   @[@"updateTime",		[typeObject objectForKey:@"updateTime"]],//上次修改时间
													   @[@"pictureFileName",[typeObject objectForKey:@"pictureFileName"]],
													   @[@"secretMode",		[typeObject objectForKey:@"secretMode"]],
													   @[@"password",		[typeObject objectForKey:@"password"]],
													   ]];
		_weakSelf.willDownloadNoteTypeCount = _weakSelf.willDownloadNoteTypeCount-1;
	}
}

@end
